<template>
  <div class="dept-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>部门管理</span>
          <el-button type="primary" @click="handleAdd" v-permission="'system:dept:add'">新增部门</el-button>
        </div>
      </template>
      <el-input v-model="depName" placeholder="请输入标题"
                style="width: 200px; margin-bottom: 10px; margin-right: 10px"/>
      <el-button type="danger" style="margin-bottom: 10px;" @click="search">搜索</el-button>
      <el-button type="info" style="margin-bottom: 10px;" @click="reSet">重置</el-button>
      <el-table
          :data="deptList"
          row-key="id"
          :tree-props="{ children: 'children' }"
          style="width: 100%"
          border
      >
        <el-table-column type="index" label="序号" width="60" align="center" fixed/>
        <el-table-column prop="name" label="部门名称" align="center"/>
        <el-table-column prop="orderNum" label="排序" width="80" align="center"/>
        <el-table-column prop="leader" label="负责人" align="center"/>
        <el-table-column prop="phone" label="联系电话" align="center"/>
        <el-table-column prop="email" label="邮箱" align="center"/>
        <el-table-column prop="status" label="状态" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row)" v-permission="'system:dept:edit'">编辑</el-button>
            <el-button type="primary" link @click="handleDelete(row)" v-permission="'system:dept:delete'">删除
            </el-button>
            <el-button type="primary" link @click="handleAssignUsers(row)" v-if="hasPermission('system:dept:assign')">
              分配用户
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          v-model:current-page="pageNum"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :small="false"
          :disabled="false"
          :background="true"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 新增/编辑部门对话框 -->
    <el-dialog
        v-model="dialogVisible"
        :title="dialogType === 'add' ? '新增部门' : '编辑部门'"
        width="500px"
    >
      <el-form
          ref="formRef"
          :model="form"
          :rules="rules"
          label-width="100px"
      >
        <el-form-item label="上级部门">
          <el-tree-select
              v-model="form.parentId"
              :data="deptOptions"
              :props="{ label: 'name', value: 'id' }"
              placeholder="请选择上级部门"
              clearable
          />
        </el-form-item>
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入部门名称"/>
        </el-form-item>
        <el-form-item label="排序" prop="orderNum">
          <el-input-number v-model="form.orderNum" :min="0" :max="999"/>
        </el-form-item>
        <el-form-item label="负责人" prop="leader">
          <el-input v-model="form.leader" placeholder="请输入负责人"/>
        </el-form-item>
        <el-form-item label="联系电话" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入联系电话"/>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="form.email" placeholder="请输入邮箱"/>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 分配用户对话框 -->
    <el-dialog
        v-model="assignDialogVisible"
        title="分配用户"
        width="600px"
    >
      <el-table
          ref="userTableRef"
          :data="userList"
          row-key="id"
          @selection-change="handleUserSelectionChange"
          style="width: 100%"
      >
        <el-table-column type="selection" width="55"/>
        <el-table-column prop="username" label="用户名"/>
        <el-table-column prop="nickname" label="昵称"/>
        <el-table-column prop="email" label="邮箱"/>
        <el-table-column prop="phone" label="手机号"/>
        <el-table-column prop="status" label="状态">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="assignDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleAssignSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {ref, onMounted, nextTick} from 'vue'
import {ElMessage, ElMessageBox, type FormInstance, type ElTable} from 'element-plus'
import {getDeptPage, addDept, updateDept, deleteDept, getDeptUsers, assignUsers} from '@/api/dept'
import {usePermission} from '@/hooks/usePermission'

interface SysDept {
  id?: number;
  parentId?: number;
  name: string;
  orderNum?: number;
  leader?: string;
  phone?: string;
  email?: string;
  status?: number;
  createTime?: string;
  updateTime?: string;
  children?: SysDept[];
}

interface DeptTreeItem {
  id: number;
  name: string;
  children?: DeptTreeItem[];
}

interface SysUser {
  id: number;
  username: string;
  nickname: string;
  email: string;
  phone: string;
  status: number;
  assigned?: boolean;
}

const deptList = ref<SysDept[]>([])
const total = ref(0)
const pageNum = ref(1)
const pageSize = ref(10)
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
const deptOptions = ref<DeptTreeItem[]>([])
const {hasPermission} = usePermission()

const form = ref({
  id: undefined,
  parentId: 0,
  name: '',
  orderNum: 0,
  leader: '',
  phone: '',
  email: '',
  status: 1
})

const rules = {
  name: [{required: true, message: '请输入部门名称', trigger: 'blur'}],
  orderNum: [{required: true, message: '请输入排序', trigger: 'blur'}],
  phone: [{pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: ['blur', 'change']}],
  email: [{type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']}]
}
const depName = ref<string>('')
const mapSysDeptToDeptTreeItem = (depts: SysDept[]): DeptTreeItem[] => {
  return depts.map(dept => ({
    id: dept.id ?? 0,
    name: dept.name,
    children: dept.children ? mapSysDeptToDeptTreeItem(dept.children) : undefined
  }));
};
const search = async () => {
  await fetchDeptList();
}
const reSet = async () => {
  depName.value = ''
  await fetchDeptList();
}
const fetchDeptList = async () => {
  const res = await getDeptPage({pageNum: pageNum.value, pageSize: pageSize.value, depName: depName.value})
  if (res.code === 200) {
    deptList.value = res.data.records
    total.value = res.data.total
    const rootOption: DeptTreeItem = {
      id: 0,
      name: '无上级部门',
      children: mapSysDeptToDeptTreeItem(res.data.records)
    }
    deptOptions.value = [rootOption]
  }
}

const handleSizeChange = (val: number) => {
  pageSize.value = val
  fetchDeptList()
}

const handleCurrentChange = (val: number) => {
  pageNum.value = val
  fetchDeptList()
}

const resetForm = () => {
  form.value = {
    id: undefined,
    parentId: 0,
    name: '',
    orderNum: 0,
    leader: '',
    phone: '',
    email: '',
    status: 1
  }
  formRef.value?.resetFields()
}

const handleAdd = () => {
  dialogType.value = 'add'
  resetForm()
  dialogVisible.value = true
}

const handleEdit = (row: any) => {
  dialogType.value = 'edit'
  form.value = {...row}
  dialogVisible.value = true
}

const handleDelete = (row: any) => {
  ElMessageBox.confirm('确认要删除该部门吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const res = await deleteDept(row.id)
    if (res.code === 200) {
      ElMessage.success('删除成功')
      fetchDeptList()
    } else {
      ElMessage.error(res.msg || '删除失败')
    }
  }).catch(() => {
  })
}

const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (valid) {
      const api = dialogType.value === 'add' ? addDept : updateDept
      const res = await api(form.value)
      if (res.code === 200) {
        ElMessage.success(dialogType.value === 'add' ? '新增成功' : '编辑成功')
        dialogVisible.value = false
        await fetchDeptList()
      } else {
        ElMessage.error(res.msg || (dialogType.value === 'add' ? '新增失败' : '编辑失败'))
      }
    }
  })
}

// 分配用户相关
const assignDialogVisible = ref(false)
const userList = ref<SysUser[]>([])
const currentDept = ref<SysDept | null>(null)
const selectedUsers = ref<SysUser[]>([])

const userTableRef = ref<InstanceType<typeof ElTable> | null>(null)

const handleUserSelectionChange = (selection: SysUser[]) => {
  selectedUsers.value = selection
}

const handleAssignUsers = async (row: SysDept) => {
  currentDept.value = row
  assignDialogVisible.value = true
  userList.value = []
  selectedUsers.value = []

  const res = await getDeptUsers(row.id!)
  if (res.code === 200) {
    userList.value = res.data
    await nextTick(() => {
      if (userTableRef.value) {
        res.data.forEach((user: SysUser) => {
          if (user.assigned) {
            userTableRef.value?.toggleRowSelection(user, true)
          }
        })
      }
    })
  }
}

const handleAssignSubmit = async () => {
  if (!currentDept.value || !currentDept.value.id) return
  const userIds = selectedUsers.value.map(user => user.id)
  const res = await assignUsers(currentDept.value.id, userIds)
  if (res.code === 200) {
    ElMessage.success('分配成功')
    assignDialogVisible.value = false
  } else {
    ElMessage.error(res.msg || '分配失败')
  }
}

onMounted(async () => {
  await fetchDeptList()
})
</script>

<style scoped>
.dept-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.el-pagination {
  margin-top: 20px;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
